package com.ruyiadmin.springboot.common.aspects.system;

import com.alibaba.fastjson.JSON;
import com.ruyiadmin.springboot.common.annotations.system.Log;
import com.ruyiadmin.springboot.common.awares.core.RuYiAdminContextAware;
import com.ruyiadmin.springboot.common.events.system.SysLogEvent;
import com.ruyiadmin.springboot.common.components.system.RuYiLogComponent;
import com.ruyiadmin.springboot.domain.entity.system.SysLog;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * <p>
 * 系统日志切面定义
 * </p>
 *
 * @author RuYiAdmin
 * @since 2022-07-20
 */
@Aspect
@Slf4j
@Component
@RequiredArgsConstructor
public class OperationLogAspect {

    private final RuYiLogComponent logUtil;

    @Around("@annotation(operationLog)")
    @SneakyThrows
    public Object around(ProceedingJoinPoint point, Log operationLog) {

        SysLog log = logUtil.getSysLog();

        log.setOperationType(operationLog.OperationType().ordinal());
        if (!StringUtils.isEmpty(operationLog.Description())) {
            log.setRemark(operationLog.Description());
        }

        if (point.getArgs().length > 0) {
            try {
                log.setParams(JSON.toJSONString(point.getArgs()));
            } catch (Exception e) {
                e.printStackTrace();
                log.setParams(Arrays.toString(point.getArgs()));
            }
        }

        //Long startTime = System.currentTimeMillis();
        Object obj;
        try {
            obj = point.proceed();
            log.setResult(JSON.toJSONString(obj));
        } catch (Exception e) {
            throw e;
        } finally {
            //Long endTime = System.currentTimeMillis();
            // 发送异步日志事件
            RuYiAdminContextAware.publishEvent(new SysLogEvent(log));
        }

        return obj;
    }

}
